查看原文
其他

《爱上Pandas》系列-你还在用VLookup吗?

小一 小一的学习笔记 2023-01-01
2020,努力做一个无可替代的人!

作者|小一

全文共2609字阅读全文需11分钟




写在前面的话

本系列最后一篇文章,我在写这节之前回顾了一下前面四篇,有种仓促结尾的感觉。
我认识一个博主,专门写Pandas 的相关教程,写了几十上百篇文章了。
也并不是说他的文章质量不高,没有的事,只是要细说Pandas的话我这五篇是真盖不住。
幸好我们不是专门研究潘大师的,我们只是潘大师的模仿者
记住我们的主要目标:数据分析。
复习一下前面的文章:
最后一篇系列文章,请珍惜潘大师最后的美好时光


正文

今天讲一个比较重要的内容,也是DataFrame 的高级应用。
在Excel 中,我们不光会用上节讲的汇总统计功能,还会用到数据表的合并、匹配
在DataFrame 中,多个数据表的合并拼接有四个方法:
  • append:提供了行方向(堆叠行)的拼接操作

  • join:提供了列方向(拼接列)的拼接操作,支持左联、右联、内联和外联四种操作类型

  • concat:通过行拼接(增加行)或列拼接(增加列)进行内联或外联拼接操作

  • merge:类似于SQL数据库操作,支持左联、右联、内联和外联等四种SQL操作类型

join 不大好用且在实际应用中用处不大,其他三个足够解决问题了。

append 操作
行方向的拼接操作,实现堆叠行的效果
数据处理过程中,经常会遇到这样一个问题:
数据格式都一样,每天一份数据,要进行汇总处理
以后遇到这个问题,数据量不是很大的话,你可以参考append 方法
# append 方法
append(self, other, ignore_index=False, sort=None):    
  • other:另一个或多个df

  • ignore_index:若为True,则对index重新索引

  • sort:若为True,则根据列标签对列排序


看个例子:
创建一个2行4列的DataFrame
# 创建一个2行4列的DataFrame
df_append_data1 = pd.DataFrame(
    np.arange(8).reshape(24),
    columns=['zhangsan''lisi''wangwu''zhaoliu']
)

# 输出
   zhangsan  lisi  wangwu  zhaoliu
0         0     1       2        3
1         4     5       6        7
通过append 方法实现两个DataFram 的堆叠行操作
# 表的堆叠行操作
df_result = df_append_data1.append(df_append_data1)

# 输出
   zhangsan  lisi  wangwu  zhaoliu
0         0     1       2        3
1         4     5       6        7
0         0     1       2        3
1         4     5       6        7
可以看到,在原有数据的下面根据列名进行数据堆叠
如果列名对应不上,会相应的填充NA 值
如果想要设置新数据的行索引,可以通过ignore_index 设置

那如果是多个DataFrame 合并呢?
多个DataFrame 合并只需要将传入的参数设置为DataFrame 列表
# 多个DataFrame 合并,并重新设置索引
df_result = df_append_data1.append([df_append_data1, df_append_data1], ignore_index=True)

# 输出
   zhangsan  lisi  wangwu  zhaoliu
0         0     1       2        3
1         4     5       6        7
2         0     1       2        3
3         4     5       6        7
4         0     1       2        3
5         4     5       6        7
可以看到,对三个DataFrame 进行合并,且对数据结果的索引进行了重新生成操作

concat 操作
行拼接或列拼接的操作,实现增加行或增加列的效果
concat 可以用来进行两个表的行列拼接操作,具体拼接方式有内联或外联两种
如果你想过数据库操作,应该知道内联和外联的意思,我简单解释一下:
  • 内联:两个数据集的交集

  • 外联:交个数据集的并集


concat 的函数是这样的:(只列举部分重要参数)
# concat 操作
concat(objs, axis=0, join=‘outer’, ignore_index=False,...)
  • axis:拼接轴方向,默认为0,按行拼接

  • join:连接方式,默认外联(outer)

  • ignore_index:若为True,则对index进行索引


关于axis 这个概念可能刚开始大家会记混,我说下自己的记忆方法:
axis=0,按行拼接,新增行数据
asix=1,按列拼接,新增列数据
关于join 内联、外联的两种方式,我画个图你们看一下(记住这个图)

内联:C部分(去重后)即:交集
外联:A+B+C部分(去重后)即:并集

概念说完了,来看例子吧。
举个例子:如果有一组数据表示A,包含张三、李四的数学和英语成绩;有另一组数据表示B,包含张三、赵六的数学和Python成绩,如何联立两个数据集?
这个例子中,我们只能对两个数据集取外联,因为内联只会保留数学成绩
# 创建DataFrame
df_concat_data_1 = pd.DataFrame(
    [['zhangsan'9088], ['lisi'9192]],
    columns=['Name''Maths''English']
)
df_concat_data_2 = pd.DataFrame(
    [['zhangsan'9075], ['zhaoliu'5899]],
    columns=['Name''Maths''Python']
)

# concat 操作
df_result = pd.concat([df_concat_data_1, df_concat_data_2], join='outer', axis=0, ignore_index=True)

# 输出
   English  Maths      Name  Python
0     88.0     90  zhangsan     NaN
1     92.0     91      lisi     NaN
2      NaN     90  zhangsan    75.0
3      NaN     58   zhaoliu    99.0
其中,concat 中的join 和axis 都维持默认设置,写出来不过是为了看的更清楚
concat 只能对数据进行简单的拼接,而上面例子中的张三应该是一个人,但是却并不通过concat 实现匹配功能
为了实现匹配这个功能,对,用merge 操作!

merge 操作
类似于SQL数据库操作,实现不同数据表的数据匹配的效果
再来看一下上面的例子用merge 函数是什么结果吧
# merge 操作
pd.merge(df_concat_data_1, df_concat_data_2, how='outer', on='Name'

# 输出
       Name  Maths_x  English  Maths_y  Python
0  zhangsan     90.0     88.0     90.0    75.0
1      lisi     91.0     92.0      NaN     NaN
2   zhaoliu      NaN      NaN     58.0    99.0
看见了没?merge 函数会根据name 列对数据进行匹配合并,这才是我们想要的结果

具体了解一下merge 函数的用法:
merge(left, right, how=‘inner’, on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=True, suffixes=(’_x’, ‘_y’))
比起concat 操作,merge 的重要参数多了很多,简单介绍一下:
  • left、right:两个要合并的DataFrame

  • how:两个DataFrame 的连接方式,默认为inner,还有 outer、left、right三种

  • on:用于连接的列名称,若未指定,默认以两个DataFrame 的列名交集为连接键

  • left_on:左侧DataFrame 用于连接的列名

  • right_on:右侧DataFrame 用于连接的列名

  • left_index:使用左侧DataFrame 的行索引作为连接键

  • right_index:使用右侧DataFrame 的行索引作为连接键

  • sort:默认为True,将合并的数据进行排序

  • suffixes:指定左右DataFrame 存在相同列名时的后缀显示


解释一个,连接方式中多了left、right 两种连接。还记得上面的图吗?

其中,inner、outer、left、right分别表示:
  • inner:C部分(去重后)

  • outer:A+B+C部分(去重后)

  • left:A部分+(C部分)

  • right:B部分+(C部分)

注意:这里面说的表示哪一部分其实不太恰当,恰当的说法应该是以哪一部分为主去进行匹配,匹配到的填充值进去,匹配不到的填充NA,注意一下。

在匹配的过程中可以左边是列名,右边是索引,进行匹配
pd.merge(df_data_1, df_data_2, left_on='key', right_index=True)
这种操作是完全可行的,
再比如,两个DataFrame 中都有Maths 这一列,匹配的时候可以通过suffixes 指定后缀显示
pd.merge(df_data_1, df_data_2, on='key', suffixes('_left''_right'))
常用的操作基本就这些,足以应付日常数据的处理
这部分一定要记得活学活用


总结一下:

这节内容的重点还是挺唯一的:数据表连接匹配
有多少人在用Excel 做数据匹配的时候电脑卡死?只是因为他们不会今天的这些内容
再来回顾一下,一共有三种方法:
  • append:提供了行方向的拼接操作

  • concat:通过行拼接或列拼接进行内联或外联操作

  • merge:类似于SQL数据库操作,支持全四种连接类型

希望对你在数据处理过程中能有所帮助,有问题可以评论区留言或者加群交流噢。
我们下个系列见

写在后面的话

应该还有分组聚合这一块没有提到,也是一个很常用的技能,有兴趣的同学自己了解一下
今天就不多说了,大家有空多看看文章,能支持的就支持一下,暖男在此谢过!



好巧啊,你也读到这了!    

点个在看让小一看到你

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存